﻿#include "IdaTitleBar.h"

#include <QToolButton>
#include <QMainWindow>
#include <QWindow>
#include <QMouseEvent>
#include <QEvent>
#include <QPoint>
#include <QLabel>
#include <QIcon>
#include <QHBoxLayout>
#include <QApplication>
#include <QScreen>
#include <QDebug>

#include "BaseModule/APIHelperWindows.h"

class TitleBarPrivate 
{
public:
    bool m_mouse_left_pressing = false;     //鼠标左键按下状态记录
    bool m_is_mainwindow = false;     //是主窗体
    QPoint m_move_start_mouse_point;        //窗口移动时鼠标起始位置
    QPoint m_move_start_window_point;       //窗口移动时窗口起始位置
    Qt::WindowStates m_window_state; //窗体状态
    QMainWindow* m_window{};                  //获取主窗口指针，默认为QMainWindow
    QLabel* m_icon_label{};                   //窗口图标
    QLabel* m_spacer_label{};                 //图标和标题的间隔
    QLabel* m_title_label{};                  //窗口标题
    QWidget* m_toolbar_seat{};                //标题中部占位
    QAction* m_action_min{};          //最小化
    QAction* m_action_max{};          //最大化
    QAction* m_action_restore{};      //窗口化
    QAction* m_action_close{};        //关闭
    BaseWidget::ETitleBars m_eTitleBars;    //标题栏按钮类型
    bool m_isUseIcon = false;
    QIcon m_icon;
    //QScreen* m_screen_default{};          //开始时的屏幕
};

IdaTitleBar::IdaTitleBar(QWidget* parent) 
    : QToolBar(parent)
    , m_private(new TitleBarPrivate)
{
    setMovable(false);  //不允许拖动

    //默认包含三个按钮
    m_private->m_eTitleBars = BaseWidget::ETitleBar::Close | BaseWidget::ETitleBar::Minimize | BaseWidget::ETitleBar::Maximize;

    //自定义标题初始化--直接操作主窗口，降低使用复杂性
    auto _window = qobject_cast<QMainWindow*>(window());
    if (_window)
    {
        m_private->m_window = _window;
        m_private->m_window->setWindowFlags(m_private->m_window->windowFlags() | Qt::FramelessWindowHint);//主窗口隐藏标题栏
        m_private->m_window->addToolBar(this);//把标题栏添加到主窗口
        m_private->m_window->addToolBarBreak();
        m_private->m_window->installEventFilter(this);//事件过滤器
    }
    else
    {
        throw QStringLiteral("不能将窗体转换为QMainWindow*.");
    }

    //左侧显示Icon和标题
    m_private->m_icon_label = new QLabel(this);
    //m_private->icon_label->setFixedSize(QSize(18, 18));
    m_private->m_icon_label->setScaledContents(true);
    m_private->m_icon_label->setPixmap(m_private->m_window->windowIcon().pixmap(m_private->m_icon_label->size()));
    m_private->m_icon_label->setAttribute(Qt::WA_TranslucentBackground);
    m_private->m_spacer_label = new QLabel(this);
    m_private->m_spacer_label->setFixedSize(QSize(1, 6));
    m_private->m_spacer_label->setAttribute(Qt::WA_TranslucentBackground);
    m_private->m_title_label = new QLabel(this);
    m_private->m_title_label->setObjectName("m_title_label");
    //m_private->m_title_label->setFont(QFont(QApplication::font().rawName(), -1, QFont::Bold));
    m_private->m_title_label->setText(m_private->m_window->windowTitle());
    m_private->m_title_label->setAttribute(Qt::WA_TranslucentBackground);
    addWidget(m_private->m_icon_label);
    addWidget(m_private->m_spacer_label);
    addWidget(m_private->m_title_label);


    //中部占位
    m_private->m_toolbar_seat = new QWidget(this);
    m_private->m_toolbar_seat->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    m_private->m_toolbar_seat->setAttribute(Qt::WA_TranslucentBackground);
    addWidget(m_private->m_toolbar_seat);

    //右侧显示最小化、最大化、关闭按钮
    auto _toolButton_min = new QToolButton(this);
    auto _toolButton_max = new QToolButton(this);
    auto _toolButton_restore = new QToolButton(this);
    auto _toolButton_close = new QToolButton(this);

    _toolButton_min->setObjectName("m_toolButton_min");
    _toolButton_max->setObjectName("m_toolButton_max");
    _toolButton_restore->setObjectName("m_toolButton_restore");
    _toolButton_close->setObjectName("m_toolButton_close");

    //m_private->toolButton_min->setFixedSize(18, 18);
    //m_private->toolButton_max->setFixedSize(18, 18);
    //m_private->toolButton_restore->setFixedSize(18, 18);
    //m_private->toolButton_close->setFixedSize(18, 18);
    _toolButton_min->setFixedSize(24, 16);
    _toolButton_max->setFixedSize(24, 16);
    _toolButton_restore->setFixedSize(24, 16);
    _toolButton_close->setFixedSize(32, 16);

    //m_private->toolButton_min->setIcon(QIcon(icon_min));
    //m_private->toolButton_max->setIcon(QIcon(icon_max));
    //m_private->toolButton_restore->setIcon(QIcon(icon_restore));
    //m_private->m_action_close->setIcon(QIcon(":/icon_window_close.png"));

    m_private->m_action_min = addWidget(_toolButton_min);
    m_private->m_action_max = addWidget(_toolButton_max);
    m_private->m_action_restore = addWidget(_toolButton_restore);
    m_private->m_action_close = addWidget(_toolButton_close);

    // 隐藏窗口化按钮
    m_private->m_action_restore->setVisible(false);

    connect(_toolButton_min, SIGNAL(clicked(bool)), this, SLOT(slot_minimizeButtonClicked()));
    connect(_toolButton_max, SIGNAL(clicked(bool)), this, SLOT(slot_maximizeButtonClicked()));
    connect(_toolButton_restore, SIGNAL(clicked(bool)), this, SLOT(slot_maximizeButtonClicked()));
    connect(_toolButton_close, SIGNAL(clicked(bool)), this, SLOT(slot_closeButtonClicked()));


    for (auto _screen : qApp->screens())
    {
        connect(_screen, &QScreen::logicalDotsPerInchChanged,this, [=](qreal dpi) 
            {
                // dpi发生变化
                changeWindowSize();
                qInfo() << QStringLiteral("dpi 发生变化. value = %1.").arg(dpi);
            }, Qt::UniqueConnection);
    }
    //m_private->m_screen_default = qApp->screenAt(window()->geometry().center());
}

IdaTitleBar::~IdaTitleBar()
{
    if (m_private)
    {
        delete m_private;
        m_private = nullptr;
    }
}


void IdaTitleBar::mouseDoubleClickEvent(QMouseEvent* event)
{
    if (Qt::LeftButton == event->button())
        slot_maximizeButtonClicked();
    event->ignore();
    QToolBar::mouseDoubleClickEvent(event);
}

void IdaTitleBar::mousePressEvent(QMouseEvent* event)
{
    if (Qt::LeftButton == event->button())
    {
        m_private->m_mouse_left_pressing = true;
        m_private->m_move_start_mouse_point = APIHelperWindowsInstance->getGlobalMousePos();
        m_private->m_move_start_window_point = APIHelperWindowsInstance->getGlobalWindowPos();
    }
    event->ignore();
    QToolBar::mousePressEvent(event);
}

void IdaTitleBar::mouseReleaseEvent(QMouseEvent* event)
{
    if (Qt::LeftButton == event->button())
        m_private->m_mouse_left_pressing = false;
    event->ignore();
    QToolBar::mouseReleaseEvent(event);
}

void IdaTitleBar::mouseMoveEvent(QMouseEvent* event)
{
    if (m_private->m_mouse_left_pressing)
    {
#ifdef Q_OS_WIN
        QPoint _globalMousePosNow = APIHelperWindowsInstance->getGlobalMousePos();  //当前鼠标的位置
        QPoint _moveValueMouse = _globalMousePosNow - m_private->m_move_start_mouse_point;  //鼠标移动的矢量
        APIHelperWindowsInstance->moveWindow(_moveValueMouse + m_private->m_move_start_window_point);
#endif
    }

    event->ignore();
    QToolBar::mouseMoveEvent(event);
}


bool IdaTitleBar::eventFilter(QObject* obj, QEvent* event)
{
    switch (event->type())
    {
    case QEvent::WindowTitleChange: //标题修改
    {
        m_private->m_title_label->setText(m_private->m_window->windowTitle());
        break;
    }
    case QEvent::WindowIconChange: //图标修改
    {
        if (m_private->m_isUseIcon)
        {
            m_private->m_icon_label->setPixmap(m_private->m_icon.pixmap(m_private->m_icon_label->height()));
        }
        else
        {
            m_private->m_icon_label->setPixmap(m_private->m_window->windowIcon().pixmap(m_private->m_icon_label->height()));
        }
        break;
    }
    case QEvent::WindowStateChange:    //窗体状态变化
    {
        m_private->m_window_state = m_private->m_window->windowState();
        emit this->signal_windowStateChange(m_private->m_window_state);
        if (Qt::WindowMaximized == m_private->m_window_state
            || Qt::WindowFullScreen == m_private->m_window_state
            || (Qt::WindowMaximized | Qt::WindowFullScreen) == m_private->m_window_state)
        {
            m_private->m_action_max->setVisible(false);
            m_private->m_action_restore->setVisible(true);
        }
        else
        {
            m_private->m_action_max->setVisible(true);
            m_private->m_action_restore->setVisible(false);
        }
        break;
    }
    case QEvent::ScreenChangeInternal:
    {
        if (m_private->m_is_mainwindow)
        {
            changeWindowSize();
        }
        break;
    }
    case QEvent::WinIdChange:
    {
        if (m_private->m_is_mainwindow && m_private->m_window->windowState() == Qt::WindowNoState)
        {
            changeWindowSize();
        }
        break;
    }
    default:
        break;
    }
    return QToolBar::eventFilter(obj, event);
}

void IdaTitleBar::slot_minimizeButtonClicked()
{
    m_private->m_window->showMinimized();
}

void IdaTitleBar::slot_maximizeButtonClicked()
{
    if (m_private->m_eTitleBars & (int)BaseWidget::ETitleBar::Maximize)
    {
        Qt::WindowStates state = m_private->m_window->windowState();
        if (Qt::WindowMaximized == state || Qt::WindowFullScreen == state || (Qt::WindowMaximized | Qt::WindowFullScreen) == state)
        {
            window()->setWindowState(Qt::WindowNoState);//将窗体正常显示
        }
        else
        {
            window()->setWindowState(Qt::WindowMaximized);//将窗体最大化
        }
    }
}

void IdaTitleBar::setInitializationWindowMaximization()
{
    this->slot_maximizeButtonClicked();
}

void IdaTitleBar::setIcon(const QIcon& icon)
{
    m_private->m_isUseIcon = true;
    m_private->m_icon = icon;
    m_private->m_icon_label->setFixedSize(QSize(16, 16));
}

void IdaTitleBar::slot_closeButtonClicked()
{
    emit this->signal_closeButtonClick();
}


void IdaTitleBar::setWindowButtonType(BaseWidget::ETitleBars type)
{
    m_private->m_eTitleBars = type;
    //没有按钮
    if (type == (int)BaseWidget::ETitleBar::None)
    {
        m_private->m_action_min->setVisible(false);
        m_private->m_action_max->setVisible(false);
        m_private->m_action_restore->setVisible(false);
        m_private->m_action_close->setVisible(false);
    }
    //只有关闭按钮
    else if (type == (int)BaseWidget::ETitleBar::Close)
    {
        m_private->m_action_min->setVisible(false);
        m_private->m_action_max->setVisible(false);
        m_private->m_action_restore->setVisible(false);
    }
    //只有关闭、最小化按钮
    else if (type == (BaseWidget::ETitleBar::Close | BaseWidget::ETitleBar::Minimize))
    {
        m_private->m_action_max->setVisible(false);
    }
    //只有关闭、最大化按钮
    else if (type == (BaseWidget::ETitleBar::Close | BaseWidget::ETitleBar::Maximize))
    {
        m_private->m_action_min->setVisible(false);
        Qt::WindowStates state = window()->windowState();
        if (Qt::WindowMaximized == state || Qt::WindowFullScreen == state || (Qt::WindowMaximized | Qt::WindowFullScreen) == state)
        {
            m_private->m_action_max->setVisible(false);
            m_private->m_action_restore->setVisible(true);
        }
        else
        {
            m_private->m_action_max->setVisible(true);
            m_private->m_action_restore->setVisible(false);
        }
    }
    //只有关闭、最小化按钮、最大化按钮
    else if (type == (BaseWidget::ETitleBar::Close | BaseWidget::ETitleBar::Minimize | BaseWidget::ETitleBar::Maximize))
    {
        Qt::WindowStates state = window()->windowState();
        if (Qt::WindowMaximized == state || Qt::WindowFullScreen == state || (Qt::WindowMaximized | Qt::WindowFullScreen) == state)
        {
            m_private->m_action_max->setVisible(false);
            m_private->m_action_restore->setVisible(true);
        }
        else
        {
            m_private->m_action_max->setVisible(true);
            m_private->m_action_restore->setVisible(false);
        }
    }
    else
    {
        m_private->m_action_min->setVisible(false);
        m_private->m_action_max->setVisible(false);
        m_private->m_action_restore->setVisible(false);
        m_private->m_action_close->setVisible(false);
    }
}

BaseWidget::ETitleBars IdaTitleBar::getWindowButtonType()
{
    return m_private->m_eTitleBars;
}

void IdaTitleBar::setIsMainWindow(bool isMainWindow)
{
    m_private->m_is_mainwindow = isMainWindow;
}

void IdaTitleBar::setHeight(int height)
{
     setFixedHeight(height);
}

void IdaTitleBar::setTitleFontSize(int size)
{
    auto _font = qApp->font();
    _font.setPixelSize(size);
    _font.setPointSize(size);
    m_private->m_title_label->setFont(_font);
}

void IdaTitleBar::changeWindowSize()
{
    if (m_private == nullptr)
    {
        //qDebug() << "m_private == nullptr";
        return;
    }
    if (m_private->m_window == nullptr)
    {
        //qDebug() << "m_private->m_window == nullptr";
        return;
    }
    if (m_private->m_window->windowHandle() == nullptr)
    {
        //qDebug() << "m_private->m_window->windowHandle() == nullptr";
        return;
    }
    if (m_private->m_window->windowHandle()->screen())
    {
        //qDebug() << "m_private->m_window->windowHandle()->screen() == nullptr";
        return;
    }
    //auto _screenDefault = m_private->m_screen_default;
    auto _screenNow = m_private->m_window->windowHandle()->screen();
    QSize _screenSizeNow = _screenNow->size();
    QSize _windowSizeNew = _screenSizeNow * 0.8;    //界面大小为屏幕大小的0.8
    _windowSizeNew = QSize(_windowSizeNew.width(), _windowSizeNew.width() * 9 / 16);    //宽高比为16 : 9

    //qDebug() << " m_private->m_screen_now = " << _screenNow->name() << " || _windowSizeNew = " << _windowSizeNew << " || _screenSizeNow = " << _screenSizeNow;
    m_private->m_window->resize(_windowSizeNew);
}

